//bange_simplestring.cpp
//Copyright (C) 2010-2011 Oscar (.teri) Triano

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include <bange_simplestring.hpp>

void bange::simplestring::RegisterVM(lua_State *vm){
	luaL_Reg method[] = {
	{"AddChar", bangesimplestring_AddChar},
	{NULL, NULL}};
	luaL_newmetatable(vm, "bange::simplestring_method");
	luaL_register(vm, NULL, method);
	lua_pop(vm, 1);
}

bange::simplestring::simplestring(lua_State *vm): sf::String(""), bange::object(vm){
	this->reffont = LUA_REFNIL;
	this->drawable = static_cast<sf::Drawable *>(this);
}

bange::simplestring::simplestring(const char *text, lua_State *vm):
sf::String(text), bange::object(vm){
	this->reffont = LUA_REFNIL;
	this->drawable = static_cast<sf::Drawable *>(this);
}

bool bange::simplestring::NewIndex(lua_State *vm){
	//simplestring, key, data
	if(this->object::NewIndex(vm)){
		return true;}
	else if (this->behavior::NewIndex(vm)){
		return true;}
	char key[64] = {0};
	strncpy(key, lua_tostring(vm, 2), 64);
	if (strcmp("text", key) == 0 && lua_isstring(vm, 3)){
		this->SetText(lua_tostring(vm, 3));
		return true;}
	if (strcmp("size", key) == 0 && lua_isnumber(vm, 3)){
		this->SetSize(lua_tonumber(vm, 3));
		return true;}
	if (strcmp("font", key) == 0 && lua_isuserdata(vm, 3)){
		sf::Font *font = dynamic_cast<sf::Font *>(bange::base::GetBaseFromProxy(3, vm));
		if (font == NULL){
			return true;}
		this->SetFont(*font);
		luaL_unref(vm, LUA_REGISTRYINDEX, this->reffont);
		this->reffont = luaL_ref(vm, LUA_REGISTRYINDEX);
		return true;}
	else if(strcmp("font", key) == 0 && lua_isnil(vm, 3)){
		luaL_unref(vm, LUA_REGISTRYINDEX, this->reffont);
		this->SetFont(sf::Font::GetDefaultFont());
		return true;}
	if (strcmp("bold", key) == 0 && lua_isboolean(vm, 3)){
		unsigned long style = this->GetStyle();
		bool set = static_cast<bool>(lua_toboolean(vm, 3));
		if (set == true){
			style |= sf::String::Bold;
		}else if(set == false && (style & sf::String::Bold) == sf::String::Bold){
			style ^= sf::String::Bold;}
		this->SetStyle(style);
		return true;}
	if (strcmp("italic", key) == 0 && lua_isboolean(vm, 3)){
		unsigned long style = this->GetStyle();
		bool set = static_cast<bool>(lua_toboolean(vm, 3));
		if (set == true){
			style |= sf::String::Italic;
		}else if(set == false && (style & sf::String::Italic) == sf::String::Italic){
			style ^= sf::String::Italic;}
		this->SetStyle(style);
		return true;}
	if (strcmp("underlined", key) == 0 && lua_isboolean(vm, 3)){
		unsigned long style = this->GetStyle();
		bool set = static_cast<bool>(lua_toboolean(vm, 3));
		if (set == true){
			style |= sf::String::Underlined;
		}else if(set == false && (style & sf::String::Underlined) == sf::String::Underlined){
			style ^= sf::String::Underlined;}
		this->SetStyle(style);
		return true;}
	return false;
}

bool bange::simplestring::Index(lua_State *vm){
	//simplestring, key
	if(this->object::Index(vm)){
		return true;}
	else if (this->behavior::Index(vm)){
		return true;}
	char key[64] = {0};
	strncpy(key, lua_tostring(vm, 2), 64);
	if (strcmp("text", key) == 0){
		lua_pushstring(vm, std::string(this->GetText()).c_str());
		return true;}
	if (strcmp("size", key) == 0){
		lua_pushnumber(vm, this->GetSize());
		return true;}
	if (strcmp("font", key) == 0){
		lua_rawgeti(vm, LUA_REGISTRYINDEX, this->reffont);
		return true;}
	if (strcmp("bold", key) == 0){
		unsigned long style = this->GetStyle();
		if( (style & sf::String::Bold) == sf::String::Bold ){
			lua_pushboolean(vm, 1);
		}else{
			lua_pushboolean(vm, 0);}
		return true;}
	if (strcmp("italic", key) == 0){
		unsigned long style = this->GetStyle();
		if( (style & sf::String::Italic) == sf::String::Italic ){
			lua_pushboolean(vm, 1);
		}else{
			lua_pushboolean(vm, 0);}
		return true;}
	if (strcmp("underlined", key) == 0){
		unsigned long style = this->GetStyle();
		if( (style & sf::String::Underlined) == sf::String::Underlined ){
			lua_pushboolean(vm, 1);
		}else{
			lua_pushboolean(vm, 0);}
		return true;}
	lua_getfield(vm, LUA_REGISTRYINDEX, "bange::simplestring_method");
	lua_getfield(vm, -1, key);
	if(lua_isfunction(vm, -1)){
		return true;}
	lua_pop(vm, 1);
	return false;
}

void bange::simplestring::AddChar(sf::Uint32 character){
	sf::Unicode::Text currenttext = this->GetText();
	sf::Unicode::UTF32String text = sf::Unicode::UTF32String(currenttext);
	this->SetText(text + character);
}

void bange::simplestring::CleanVM(lua_State *vm){
	luaL_unref(vm, LUA_REGISTRYINDEX, this->reffont);
	this->bange::behavior::CleanVM(vm);
}

bange::simplestring::~simplestring(){
	cout << "bange::simplestring destructor for: " << this << endl;
}

static int bangesimplestring_AddChar(lua_State *vm){
	//simplestring, number (unicode)
	bange::simplestring *simplestring = dynamic_cast<bange::simplestring *>(bange::base::GetBaseFromProxy(1, vm));
	simplestring->AddChar(static_cast<sf::Uint32>(lua_tonumber(vm, 2)));
	return 0;
}
